// 生成数独解决方案
const Toolkit = require('./toolkit');

module.exports = class Generator {
  generate() {
    while (!this.internalgenerate()) {
      console.log('try again')
    }
  }

  internalgenerate() {
    // 入口解决方案
    // 先生成矩阵
    this.matrix = Toolkit.matrix.makeMatrix();
    this.orders = Toolkit.matrix.makeMatrix()
      .map(row => row.map((v, i) => i))
      .map(row => Toolkit.matrix.shuffle(row));       //将顺序打乱

    // Toolkit.matrix.makeRow()
    //   .every((n))
    for (let n = 1; n <= 9; n++) {
      if (!this.fillNumber(n)) {
        return false;
      }

    }
    return true
  }

  fillNumber(n) {
    // 填数操作
    // 填入行数据
    return this.fillRow(n, 0);
  }

  fillRow(n, rowIndex) {
    // 填入行 结束
    if (rowIndex > 8) {
      return true
    }
    const row = this.matrix[rowIndex];
    // 随机选择列
    const orders = this.orders[rowIndex];
    for (let i = 0; i < 9; i++) {
      // const colIndex = i;
      const colIndex = orders[i];
      // 当前位置已有数据
      if (row[colIndex]) {
        continue;
      }
      // 检查当前位置是否可以填 n
      if (!Toolkit.matrix.checkFillAble(this.matrix, n, rowIndex, colIndex)) {
        continue;
      }
      row[colIndex] = n;
      // 当前行填写 n 成功，递归调用 fillRow 来在下一行中填写 n
      // 去下一行提填写 n，如果没填进去，就去当前行的下一个位置填写
      if (!this.fillRow(n, rowIndex + 1)) {
        row[colIndex] = 0;
        continue;
      }
      return true;
    }
    return false;
  }
}

// const generator = new Generator();
// generator.generate();
// console.log(generator.matrix)
